﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Data;
using AcctrueWMS.Foundation.Common.Exception;
using System.Web;
using AcctrueWMS.Foundation.Web;
using AcctrueWMS.Foundation.Data;
using AcctrueWMS.Foundation.Common;
using AcctruePMS.Bll.Common;
using System.Configuration;
using System.IO;

namespace AcctruePMS.Bll.Manager
{
    public class LogManager
    {
        #region 写入日志
        /// <summary>
        /// 操作日志记录
        /// </summary>
        /// <param name="modelName">业务模块</param>
        /// <param name="actionType">操作类型</param>
        /// <param name="details">操作详细</param>
        /// 
        public string logFolderPath = ConfigurationManager.AppSettings["logPath"];

        public void LogInfo(string modelName, string actionType, string details)
        {
            string userNo = HttpContext.Current.Session["userNo"].ToString();
            LogInfo(modelName, userNo, actionType, details);
        }
        /// <summary>
        /// 操作日志记录
        /// </summary>
        /// <param name="moduleName">业务模块</param>
        /// <param name="actionType">操作类型</param>
        /// <param name="details">操作详细[如有多个以|分割]</param>
        /// <param name="actorNo">操作人编号</param>
        public void LogInfo(string moduleName, string actorNo, string actionType, string details)
        {
            string[] strDetailsList = DateHelper.UnEscape(details).Split('|');
            StringBuilder strblderList = new StringBuilder();
            for (int i = 0; i < strDetailsList.Length; i++)
            {
                if (strDetailsList[i].IndexOf("=") > 0)
                    strblderList.Append(strDetailsList[i].Split('=')[1] + ",");
                else if (strDetailsList[i].Trim() != "")
                    strblderList.Append(strDetailsList[i] + ",");
            }
            string nowDate = string.Format(DateTime.Now.ToString(), "yyyy-MM-dd hh:mm");
            string info = moduleName.Replace("|", "$") + "|" + actorNo.Trim().Replace("|", "$") + "|" + nowDate + "|" + actionType.Trim().Replace("|", "$") + "|" + strblderList.ToString().Substring(0, strblderList.Length - 1);
            LoggerManager.GetLogger().Info(info);
        }

        /// <summary>
        /// 异常日志记录
        /// </summary>
        /// <param name="ex"></param>
        public void LogError(System.Exception ex)
        {
            LoggerManager.GetLogger("logerror").Error(ex);
        }
        #endregion



        #region 读取日志
        /// <summary>
        /// 获取查询条件中的键值
        /// </summary>
        /// <param name="query">字符串表达式</param>
        /// <param name="key">获取值的字段名称</param>
        /// <param name="regex">正则表达式</param>
        /// <returns></returns>
        private string GetQueryValue(string query, string key, Regex regex)
        {
            if (regex == null || regex.Equals(""))
                regex = new Regex(@"(?<name>[\w|\d]+)(\s+like\s+|\s*=\s*|<=|>=)['%]*(?<value>[^&%']+)['%]*"); 
            foreach (Match m in regex.Matches(query))
            {
                string name = m.Groups["name"].Value;
                string value = m.Groups["value"].Value;
                if (name == key)
                    return value;
            }
            return null;
        }

        /// <summary>
        /// 获取起始日期和截止日期
        /// </summary>
        /// <param name="query">查询字符串</param>
        /// <param name="key">字段名</param>
        /// <param name="type">bgn:其实日期  end:截止日期 </param>
        /// <returns></returns>
        private string GetDateCondition(string query, string key, string type)
        {
            Regex regex = null;
            if (type == "bgn")
                regex = new Regex(@"(?<name>[\w|\d]+)(\s+like\s+|\s*=\s*|>=)['%]*(?<value>[^&%']+)['%]*");  //其实日期表达式
            else
                regex = new Regex(@"(?<name>[\w|\d]+)(\s+like\s+|\s*=\s*|<=)['%]*(?<value>[^&%']+)['%]*");  // 截止日期表达式
            return GetQueryValue(query, key, regex);
        }
        
        public DataTable GetLogInfo(string condition)
        {
            if (condition.Trim() == "$request.QueryString.get('query')")
                return GetLogInfo(null, null);
            else
            {
                string beginStr = GetDateCondition(condition, "operatTime", "bgn");
                string endStr = GetDateCondition(condition, "operatTime", "end"); ;
                return GetLogInfo(beginStr, endStr);
            }          
        }

        /// <summary>
        /// 获取日志信息
        /// </summary>
        /// <param name="beginStr">起始日期</param>
        /// <param name="endStr">截止日期</param>
        /// <returns></returns>        
        public DataTable GetLogInfo(string beginStr, string endStr)
        {
            DataTable dtLogInfo = CreateLogInfoTable();
            DateTime begin = string.IsNullOrEmpty(beginStr) ? DateTime.Now.AddDays(-3) : DateTime.Parse(beginStr);
            DateTime end = string.IsNullOrEmpty(endStr) ? DateTime.Now : DateTime.Parse(endStr);
            string filePath = string.Empty;
            string fileName = string.Empty;
            for (int i = 0; i <= (end - begin).Days && i < 7; i++)
            {
                fileName = begin.AddDays(i).ToString("yyyyMMdd");
                filePath = logFolderPath +"\\"+ fileName;
                ReadLogFile(filePath, dtLogInfo);
            }
            return dtLogInfo;
        }


        /// <summary>
        /// 读取文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="dtLogInfo">填充表</param>
        private void ReadLogFile(string filePath, DataTable dtLogInfo)
        {
            if (File.Exists(filePath))
            {
                //防止文件正在被写入导致读取失败
                string tempFile = filePath + "$";
                System.IO.File.Copy(filePath, tempFile, true);
                using (FileStream fstream = new FileStream(tempFile, FileMode.Open, FileAccess.Read))
                {
                    StreamReader rstream = new StreamReader(fstream, System.Text.Encoding.GetEncoding("gb2312"));
                    string line = rstream.ReadLine();
                    string txtInfo = string.Empty;
                    while (line != null)
                    {
                        line = line.Trim();
                        if (line.IndexOf("操作信息详情：") > -1)
                        {
                            try
                            {                       
                                txtInfo = line.Substring(7, line.Length - 7);
                                string[] logInfos = txtInfo.Split('|');
                                if (logInfos.Length == 5)
                                {
                                    DataRow row = dtLogInfo.NewRow();
                                    row["model"] = logInfos[0].Replace("$", "|");
                                    row["operator"] = logInfos[1].Replace("$", "|");
                                    row["operatTime"] = logInfos[2].Replace("$", "|");
                                    row["operation"] = logInfos[3].Replace("$", "|");
                                    row["operatDetail"] = logInfos[4];
                                    dtLogInfo.Rows.Add(row);
                                }
                            }
                            catch (Exception)
                            {
                                //文件格式不正确
                            }
                        }
                        line = rstream.ReadLine();
                    }
                    rstream.Close();
                    fstream.Close();
                }
                //删除零时文件
                System.IO.File.Delete(tempFile);
            }
        }

        #endregion

        /// <summary>
        /// 构造日志table
        /// </summary>
        /// <returns></returns>
        private DataTable CreateLogInfoTable()
        {
            DataTable logInfo = new DataTable("logInfo");
            logInfo.Columns.Add("model", typeof(String));                      //业务模块
            logInfo.Columns.Add("operator", typeof(String));                 //操作类型
            logInfo.Columns.Add("operatTime", typeof(DateTime));     //操作时间
            logInfo.Columns.Add("operation", typeof(String));            //操作
            logInfo.Columns.Add("operatDetail", typeof(String));       //操作详细
            return logInfo;
        }


    }
}
